<template>
<div :class="[type === 'textarea' ? 'bh-textarea' : 'bh-input',
	inputSize ? 'bh-input--' + inputSize : '',
	{
		'is-disabled': disabled,
		'bh-input--prefix': $slots.prefix || prefixIcon,
		'bh-input--suffix': $slots.suffix || suffixIcon || clearable || showPassword
	}]"
	@mouseenter="hovering = true"
    @mouseleave="hovering = false">
    
	<template v-if="type !== 'textarea'">
		<input 
			v-bind='$attrs' 
			:type="showPassword ? (passwordVisible ? 'text': 'password') : type"
			ref='input' 
			:disabled="disabled"
			:readonly="readonly"
			class="bh-input__inner"
			@input="handleInput"
			@focus="handleFocus"
			@blur="handleBlur"
			@change="handleChange" />
		<!-- 前置内容 -->
		<span class="bh-input__prefix" v-if="$slots.prefix || prefixIcon">
			<slot name="prefix"></slot>
			<i class="bh-input__icon" v-if="prefixIcon" :class="prefixIcon"></i>
		</span>
		<!-- 后置内容 -->
		<span class="bh-input__suffix" v-if="getSuffixVisible()">
			<span class="bh-input__suffix-inner">
				<template v-if="!showClear || !showPwdVisible">
					<slot name="suffix"></slot>
					<i class="bh-input__icon" v-if="suffixIcon" :class="suffixIcon">
					</i>
				</template>
				<i v-if="showClear" @mousedown.prevent @click="clear" class="bh-input__icon bh-icon-circle-close bh-input__clear"></i>
				<i v-if="showPwdVisible" class="bh-input__icon bh-icon-view bh-input__clear" @click="handlePasswordVisible"></i>
				<span v-if="isWordLimitVisible" class="bh-input__count">
					<span class="bh-input__count-inner">
						{{ textLength }}/{{ upperLimit }}
					</span>
				</span>
			</span>
		</span>
	</template>
	<div v-else class="bh-textarea">
		<textarea 
			v-bind='$attrs' 
			ref='textarea'
			:disabled="disabled"
			:readonly="readonly"
			class="bh-textarea__inner" 
			@input="handleInput"
			@focus="handleFocus"
			@blur="handleBlur"
			@change="handleChange"></textarea>
	</div>
	<span v-if="isWordLimitVisible && type === 'textarea'" class="bh-input__count">{{ textLength }}/{{ upperLimit }}</span>
	
	
</div>
</template>

<script>
export default {
	name: 'bh-input',
	inheritAttrs: false,
	data() {
		return {
			hovering: false,
			focused: false,
			passwordVisible: false,
		};
	},
	props: {
		value: [String, Number],
		type: {
			type: String,
			default: "text",
		},
		size: String,
		suffixIcon: String,
		prefixIcon: String,
		showPassword: {
			type: Boolean,
			default: false
		},
		showWordLimit: {
			type: Boolean,
			default: false
		},
		disabled: {
			type: Boolean,
			default: false,
		},
		readonly: {
			type: Boolean,
			default: false,
		},
		clearable: {
			type: Boolean,
			default: false,
		},
		modelValue: {
			type: String,
		},
	},
	methods: {
		handleInput(event) {
			// 调用input,将子级的值传递给父级的v-model
			this.$emit('input', event.target.value);
		},
		handleFocus(event) {
			this.focused = true;
			this.$emit('focus', event);
		},
		handleBlur(event) {
			this.focused = false;
			this.$emit('blur', event);
		},
		handleChange(event) {
			this.$emit('change', event.target.value);
		},
		getSuffixVisible() {
			return this.showClear || this.showPwdVisible || this.suffixIcon || this.$slots.suffix || this.isWordLimitVisible;
		},
		//清空
		clear() {
			this.$emit('input', '');
			this.$emit('change', '');
			this.$emit('clear');
		},
		handlePasswordVisible() {
			this.passwordVisible = !this.passwordVisible;
		},

		getInput() {
			return this.$refs.input || this.$refs.textarea;
		},
		setNativeInputValue() {
			const input = this.getInput();
			if (!input) return;
			if (input.value === this.nativeInputValue) return;
			input.value = this.nativeInputValue;
		},
	},
	computed: {
		inputDisabled() {
			return this.disabled;
		},
		nativeInputValue() {
			return this.value === null || this.value === undefined ? '' : String(this.value);
		},
		inputSize() {
			return this.size;
		},
		showClear() {
			return this.clearable && !this.inputDisabled && !this.readonly && this.nativeInputValue && this.hovering;
		},
		showPwdVisible() {
			return this.showPassword &&
				!this.inputDisabled &&
				!this.readonly &&
				(!!this.nativeInputValue || this.focused);
		},

		isWordLimitVisible() {
			return this.showWordLimit &&
				this.$attrs.maxlength &&
				(this.type === 'text' || this.type === 'textarea') &&
				!this.inputDisabled &&
				!this.readonly &&
				!this.showPassword;
		},
		upperLimit() {
			return this.$attrs.maxlength;
		},
		textLength() {
			if (typeof this.value === 'number') {
				return String(this.value).length;
			}

			return (this.value || '').length;
		},
	},
	watch: {
		nativeInputValue() {
			this.setNativeInputValue();
		},
	},
	mounted() {
		this.setNativeInputValue();
	},
}
</script>
